package org.huzhp.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 重定向 重写Location url主机地址 使用RewriteLocationResponseHeaderGatewayFilterFactory
 * @Author: huzp
 * @CreateDate: 2020/3/13 13:02
 * @Version: 1.0
 */
@Component
public class LocationRewriteGatewayFilterFactory extends CommonGatewayFilterFactory<LocationRewriteGatewayFilterFactory.Config> {

    private static final String LOCATIONHEADERNAME = "Location";

    public LocationRewriteGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList();
    }


    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> responseCallBack(config, exchange)));
        };
    }

    @Override
    protected void responseCallBack(LocationRewriteGatewayFilterFactory.Config config, ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        ServerHttpRequest request = exchange.getRequest();
        String location = response.getHeaders().getFirst(LOCATIONHEADERNAME);
        if (location != null) {
            //只有是网关地址重定向到了所代理的实际地址
            URI targetURI = exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
            String targetHost =  UriComponentsBuilder.newInstance().scheme(targetURI.getScheme()).host(targetURI.getHost()).port(targetURI.getPort()).toUriString();
            URI requestURI = request.getURI();
            if (location.contains(targetHost)) {
                location = UriComponentsBuilder.fromUriString(location).scheme(requestURI.getScheme()).host(requestURI.getHost()).port(requestURI.getPort()).toUriString();
                logger.info("Location rewrite url:{}", location);
                response.getHeaders().set("Location", location);
            }
        }
    }

    public static class Config {


    }
}
